package com.authine.cloudpivot.ext.applicationservice.organization;

import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import com.alibaba.cola.exception.Exceptions;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.authine.cloudpivot.common.organization.feign.UserFeignServiceI;
import com.authine.cloudpivot.common.organization.model.enums.GenderType;
import com.authine.cloudpivot.ext.applicationservice.authority.RoleApi;
import com.authine.cloudpivot.ext.applicationservice.authority.TagScopeService;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.constants.PlatformConst;
import com.authine.cloudpivot.ext.dto.kingDee.KingDeeBusiness;
import com.authine.cloudpivot.ext.dto.kingDee.request.KingDeeMember;
import com.authine.cloudpivot.ext.dto.system.*;
import com.authine.cloudpivot.ext.enums.kingdee.BusinessType;
import com.authine.cloudpivot.ext.service.OrganizationDataService;
import com.authine.cloudpivot.ext.utils.BoServiceUtils;
import com.authine.cloudpivot.ext.utils.JdbcTemplateUtils;
import com.authine.cloudpivot.ext.utils.system.BeanUtils;
import com.authine.common.util.ObjectMapperUtils;
import com.authine.hermes.app.launcher.org.v2.UserV2;
import com.authine.hermes.app.launcher.service.ApplicationService;
import com.authine.mvp.app.launcher.domain.SelectorFormat;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.dto.bo.query.expression.Operator;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import com.authine.mvp.app.launcher.dto.errorcode.ErrorCodeEnum;
import com.authine.mvp.app.org.dto.domainmodel.UnitType;
import com.authine.mvp.app.permission.dto.clientobject.PermGroupDto;
import com.authine.mvp.app.permission.dto.clientobject.SubjectDto;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.util.*;
import java.util.stream.Collectors;

import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

/**
 * @ClassName UserApi
 * @Description: 系统管理用户api
 * @Author fj
 * @Date 2021/7/2
 * @Version V1.0
 **/
@Path("UserApi")
@Slf4j
public class UserApi extends ApplicationService {
    private static final DepartmentApi departmentApi = new DepartmentApi();
    private static final RoleApi roleApi = new RoleApi();
    private static final OrganizationApi organizationApi = new OrganizationApi();
    private static final OrganizationDataService organizationDataService = new OrganizationDataService();
    private static final UserFeignServiceI userFeignServiceI = ApplicationContextUtils.getBean(UserFeignServiceI.class);
    private static final NamedParameterJdbcTemplate jdbcTemplate = ApplicationContextUtils.getBean(NamedParameterJdbcTemplate.class);
    private static final List<String> adminRoleNames = Arrays.asList(PlatformConst.ROLE_PM_ADMIN, PlatformConst.ROLE_VENDOR_ADMIN, PlatformConst.ROLE_CUSTOMER_ADMIN);
    private static final TagScopeService tagScopeService = new TagScopeService();

    /**
     * 根据查询条件获取用户是否存在
     *
     * @param param 查询参数
     * @return 查询结果总数
     */
    @Path("userCount")
    @POST
    @Operation(summary = "根据查询条件获取用户是否存在", tags = CUSTOM_SERVICE)
    public Integer userCount(@Parameter Map<String, Object> param) {
        // 获取请求参数key
        String key = param.keySet().iterator().next();

        List<Map<String, Object>> userList = Objects.requireNonNull(JdbcTemplateUtils.builder(ModelConst.T_USER).selectField("*"))
                .eq(key, param.get(key))
                .queryForList();
        return userList.size();
    }

    /**
     * 保存用户信息
     *
     * @param user 用户信息
     * @return 响应结果
     */
    @Path("saveUser")
    @POST
    @Operation(summary = "保存用户信息", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> saveUser(@Parameter UserDto user) {
        Assert.notEmpty(user.getOrganization_id(), "用户组织不能为空");
        Assert.notEmpty(user.getDepartment_id(), "用户部门不能为空");
        SelectorFormat organization = user.getOrganization_id().get(0);
        SelectorFormat department = user.getDepartment_id().get(0);

        // 验证部门一致性
        DepartmentDto param = new DepartmentDto();
        param.setId(department.getId());
        DepartmentDto dept = departmentApi.getDept(param);
        if (!organization.equals(dept.getOrganization_id().get(0))) {
            return SingleResponse.error("-1", "部门所在的组织与当前选择的组织不一致");
        }

        setUserValue(user);

        UserV2 userV2 = buildUserV2(user);
        // 设置userBaseId
        userV2.setUserBaseId(userV2.getId());
        log.info("------------------------创建云枢用户参数信息：{}------------------------", JSONObject.toJSONString(userV2));
        SingleResponse<UserV2> userResponse = this.orgServiceV2.createUser(userV2);
        if (!userResponse.isSuccess()) {
            // 用户名重复时，云枢系统会提示账号已存在，不适用于目前系统。故做此判断
            if ("账号已存在".equals(userResponse.getErrMessage())) {
                return SingleResponse.error(userResponse.getErrCode(), "用户名已存在");
            }
            return SingleResponse.error(userResponse.getErrCode(), userResponse.getErrMessage());
        }
        log.info("------------------------云枢用户数据新增成功,用户信息：{}------------------------", JSONObject.toJSONString(userResponse));

        // 根据用户输入的密码，调用修改密码接口
        SingleResponse<?> modifyPasswordBO = userFeignServiceI.modifyPassword(userResponse.getData().getUserBaseId(), user.getEncryptedOldPassword(),
                user.getEncryptedNewPassword(), user.getIndex());
        log.info("------------------------修改云枢用户登录密码,修改结果：{}------------------------", JSONObject.toJSONString(modifyPasswordBO));

        // 系统管理id和云枢选人控件id保持一致，使用h_org_user表中的id
        user.setId(userResponse.getData().getId());

        Map<String, Object> userMap = BeanUtils.bean2Map(user);
        log.info("------------------------创建系统管理用户参数：{}------------------------", JSONObject.toJSONString(userMap));
        SingleResponse<BO> createUserBO = BoServiceUtils.createBo(ModelConst.T_USER, Collections.singletonList(userMap));
        if (!createUserBO.isSuccess()) {
            return SingleResponse.error("-3", "系统管理用户创建失败");
        }
        log.info("------------------------系统管理用户数据新增成功，用户信息：{}------------------------", JSONObject.toJSONString(createUserBO));

        // 保存信息到金蝶中
        KingDeeBusiness kingDeeBusiness = KingDeeBusiness.builder()
                .businessId(createUserBO.getData().getBizObjectId())
                .businessType(BusinessType.Employee)
                .build();
        KingDeeMember kingDeeMember = KingDeeMember.builder()
                .number(createUserBO.getData().getBizObjectId())
                .name(String.valueOf(createUserBO.getData().getData().get("username")))
                .business(kingDeeBusiness)
                .build();
        organizationDataService.createMember(kingDeeMember);

        // 如果授权方式是按人员授权，角色人员范围中增加当前用户信息；如果是按标签授权，标签人员范围中增加当前用户信息
        if (!StringUtils.isEmpty(user.getRole_ids())) {
            SingleResponse<BOList> rolePermBOList;
            SingleResponse<BO> roleBO;
            List<PermGroupDto> permGroupList = Lists.newArrayList();
            List<TagScopeDto> tagScopeDtoList;
            String[] roleIds = user.getRole_ids().split(",");
            SubjectDto subjectDto = new SubjectDto();
            subjectDto.setId(createUserBO.getData().getBizObjectId());
            subjectDto.setName(user.getUsername());
            for (String roleId : roleIds) {
                roleBO = BoServiceUtils.loadBo(roleId, ModelConst.T_ROLE);

                if ("2".equals(String.valueOf(roleBO.getData().getData().get("authType")))) {
                    // 按人员授权
                    rolePermBOList = BoServiceUtils.findListBySimple(ModelConst.T_ROLE_PERM, "role_id", roleId);
                    log.info("------------------------通过角色id获取角色权限信息：{}------------------------", JSONObject.toJSONString(rolePermBOList));

                    // 根据groupId进行分组
                    List<String> groupIdList = rolePermBOList.getData().getData().stream()
                            .map(map -> String.valueOf(map.get("group_id")))
                            .distinct()
                            .collect(Collectors.toList());
                    for (String groupId : groupIdList) {
                        // 通过角色组id获取角色组权限信息
                        SingleResponse<?> response = this.permService.queryPermGroupByPermGroupId(groupId);
                        log.info("------------------------根据角色组id获取角色组权限信息：{}------------------------", JSONObject.toJSONString(response));
                        PermGroupDto permGroupDto = ObjectMapperUtils.fromJSON(ObjectMapperUtils.toJSONString(response.getData()), PermGroupDto.class);
                        permGroupDto.getSubjectDtoList().add(subjectDto);
                        permGroupList.add(permGroupDto);
                    }
                } else if ("3".equals(String.valueOf(roleBO.getData().getData().get("authType")))) {
                    // 按标签授权
                    String tagScope = String.valueOf(roleBO.getData().getData().get("tag_scope"));

                    // 通过角色id获取对应的管理范围
                    List<String> tagScopeIdList = Arrays.asList(tagScope.split(","));
                    tagScopeDtoList = Objects.requireNonNull(JdbcTemplateUtils.builder(ModelConst.T_TAG_SCOPE).selectField("id, organization_id, group_name, group_id, tag_name, tag_id, user_ids, scope_type," +
                            "ou_scopes, us_scopes, corp_id")).in("id", tagScopeIdList).queryForPOJOList(TagScopeDto.class, true);
                    for (TagScopeDto tagScopeDto : tagScopeDtoList) {
                        SelectorFormat currentUser = user.createSelectorFormat();
                        if (CollectionUtils.isEmpty(tagScopeDto.getUser_ids())) {
                            tagScopeDto.setUser_ids(Collections.singletonList(currentUser));
                            tagScopeService.createRoleUser(tagScopeDto);
                        } else {
                            tagScopeDto.getUser_ids().add(currentUser);
                            tagScopeService.updateRoleUser(tagScopeDto);
                        }

                        // 修改管理范围
                        BoServiceUtils.updateMainBo(ModelConst.T_TAG_SCOPE, BeanUtils.bean2Map(tagScopeDto));
                    }
                }
            }
            if (!CollectionUtils.isEmpty(permGroupList)) {
                // 更新角色组信息
                log.info("------------------------更新角色组信息数据：{}------------------------", JSONObject.toJSONString(permGroupList));
                this.permService.updatePermGroupByPermGroupId(permGroupList);
            }
        }
        // todo 消息推送
        return createUserBO;
    }

    /**
     * 更新用户信息
     *
     * @param user 用户信息
     * @return 响应结果
     */
    @Path("updateUser")
    @POST
    @Operation(summary = "更新用户信息", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> updateUser(@Parameter UserDto user) {
        Assert.notNull(user.getId(), "ID不能为空");
        Assert.notEmpty(user.getOrganization_id(), "用户组织不能为空");
        Assert.notEmpty(user.getDepartment_id(), "用户部门不能为空");

        // 获取修改的用户信息
        UserDto oldUser = this.getUserByIdThroughJDBC(user);
        log.info("------------------------修改之前的用户数据map转为javaBean：{}------------------------", JSONObject.toJSONString(oldUser));
        if (!StringUtils.isEmpty(user.getPassword())) {
            if (user.getPassword().length() < 6) {
                return SingleResponse.error("-1", "密码不能小于6位");
            }
        }
        Map<String, Object> param = Maps.newHashMap();
        int total;
        if (!StringUtils.isEmpty(user.getUsername()) && !user.getUsername().equals(oldUser.getUsername())) {
            param.put("username", user.getUsername());
            total = this.userCount(param);
            if (total > 0) {
                return SingleResponse.error("-2", "用户登录名已存在");
            }
        }
        if (!StringUtils.isEmpty(user.getEmail()) && !user.getEmail().equals(oldUser.getEmail())) {
            param.clear();
            param.put("email", user.getEmail());
            total = this.userCount(param);
            if (total > 0) {
                return SingleResponse.error("-3", "用户邮箱已存在");
            }
        }
        if (!StringUtils.isEmpty(user.getCellphone()) && !user.getCellphone().equals(oldUser.getCellphone())) {
            param.clear();
            param.put("cellphone", user.getCellphone());
            total = this.userCount(param);
            if (total > 0) {
                return SingleResponse.error("-4", "手机号已存在");
            }
        }

        setUserValue(user);

        // 修改云枢用户
        UserV2 userV2 = buildUserV2(user);
        log.info("------------------------修改云枢用户参数信息：{}------------------------", JSONObject.toJSONString(userV2));
        SingleResponse<UserV2> userResponse = this.orgServiceV2.updateUser(userV2);
        if (!userResponse.isSuccess()) {
            // 用户名重复时，云枢系统会提示账号已存在，不适用于目前系统。故做此判断
            if ("账号已存在".equals(userResponse.getErrMessage())) {
                return SingleResponse.error(userResponse.getErrCode(), "用户名已存在");
            }
            return SingleResponse.error(userResponse.getErrCode(), userResponse.getErrMessage());
        }
        log.info("------------------------修改云枢用户成功,修改结果：{}------------------------", JSONObject.toJSONString(userResponse));

        SingleResponse<UserV2> userByUserId = orgServiceV2.getUserByUserId(userResponse.getData().getId());
        // 修改密碼
        if (!oldUser.getPassword().equals(user.getPassword())) {
            SingleResponse<?> modifyPasswordBO = userFeignServiceI.modifyPassword(userByUserId.getData().getUserBaseId(), user.getEncryptedOldPassword(),
                    user.getEncryptedNewPassword(), user.getIndex());
            log.info("------------------------修改云枢用户登录密码,修改结果：{}------------------------", JSONObject.toJSONString(modifyPasswordBO));
        }

        // 系统管理用户修改
        Map<String, Object> userMap = BeanUtils.bean2Map(user);
        log.info("------------------------修改系统管理用户参数：{}------------------------", JSONObject.toJSONString(userMap));
        SingleResponse<BO> updateUserBO = BoServiceUtils.updateMainBo(ModelConst.T_USER, userMap);
        if (!updateUserBO.isSuccess()) {
            return SingleResponse.error("-4", "系统管理用户修改失败");
        }

        // 记录用户修改记录
        JSONObject newUserJSON = JSON.parseObject(JSON.toJSONString(user, SerializerFeature.WRITE_MAP_NULL_FEATURES));
        log.info("------------------------修改之后的用户数据javaBean转为json：{}------------------------", JSONObject.toJSONString(newUserJSON));
        JSONObject oldUserJSON = JSON.parseObject(JSON.toJSONString(oldUser, SerializerFeature.WRITE_MAP_NULL_FEATURES));
        log.info("------------------------修改之前的用户数据javaBean转为json：{}------------------------", JSONObject.toJSONString(oldUserJSON));

        this.userRecord(newUserJSON, oldUserJSON);

        // 角色组授权范围增加当前用户信息
        List<String> oldRoleIdList = StringUtils.isEmpty(oldUser.getRole_ids()) ? Lists.newArrayList() : Arrays.stream(oldUser.getRole_ids().split(",")).collect(Collectors.toList());
        List<String> newRoleIdList = StringUtils.isEmpty(user.getRole_ids()) ? Lists.newArrayList() : Arrays.stream(user.getRole_ids().split(",")).collect(Collectors.toList());

        // 获取角色id差集
        List<String> differentIdList = getDifferenceList(oldRoleIdList, newRoleIdList);

        // 如果授权方式是按人员授权，角色人员范围中增加当前用户信息
        if (!differentIdList.isEmpty()) {
            SingleResponse<BOList> rolePermBOList;
            SingleResponse<BO> roleBO;
            // 角色人员
            List<PermGroupDto> permGroupList = Lists.newArrayList();
            List<TagScopeDto> tagScopeDtoList;
            SubjectDto subjectDto = new SubjectDto();
            subjectDto.setId(user.getId());
            subjectDto.setName(user.getUsername());
            for (String roleId : differentIdList) {
                // 如果授权方式是按人员授权，角色人员范围中增加当前用户信息
                roleBO = BoServiceUtils.loadBo(roleId, ModelConst.T_ROLE);

                if ("2".equals(String.valueOf(roleBO.getData().getData().get("authType")))) {
                    // 按人员授权
                    rolePermBOList = BoServiceUtils.findListBySimple(ModelConst.T_ROLE_PERM, "role_id", roleId);
                    log.info("------------------------通过角色id获取角色权限信息：{}------------------------", JSONObject.toJSONString(rolePermBOList));

                    // 根据groupId进行分组
                    List<String> groupIdList = rolePermBOList.getData().getData().stream()
                            .map(map -> String.valueOf(map.get("group_id")))
                            .distinct()
                            .collect(Collectors.toList());
                    for (String groupId : groupIdList) {
                        // 通过角色组id获取角色组权限信息
                        SingleResponse<?> response = this.permService.queryPermGroupByPermGroupId(groupId);
                        log.info("------------------------根据角色组id获取角色组权限信息：{}------------------------", JSONObject.toJSONString(response));
                        PermGroupDto permGroupDto = ObjectMapperUtils.fromJSON(ObjectMapperUtils.toJSONString(response.getData()), PermGroupDto.class);

                        if (newRoleIdList.contains(roleId)) {
                            // 修改用户时新增的角色id，角色组授权范围中添加用户
                            permGroupDto.getSubjectDtoList().add(subjectDto);
                        } else {
                            // 修改用户时删除的角色id，角色组授权范围中删除用户
                            permGroupDto.getSubjectDtoList().remove(subjectDto);
                        }
                        permGroupList.add(permGroupDto);
                    }
                } else if ("3".equals(String.valueOf(roleBO.getData().getData().get("authType")))) {
                    // 按标签授权
                    String tagScope = String.valueOf(roleBO.getData().getData().get("tag_scope"));

                    // 通过角色id获取对应的管理范围
                    List<String> tagScopeIdList = Arrays.asList(tagScope.split(","));
                    tagScopeDtoList = Objects.requireNonNull(JdbcTemplateUtils.builder(ModelConst.T_TAG_SCOPE).selectField("id, organization_id, group_name, group_id, tag_name, tag_id, user_ids, scope_type," +
                            "ou_scopes, us_scopes, corp_id")).in("id", tagScopeIdList).queryForPOJOList(TagScopeDto.class, true);
                    for (TagScopeDto tagScopeDto : tagScopeDtoList) {
                        SelectorFormat currentUser = user.createSelectorFormat();
                        if (newRoleIdList.contains(roleId)) {
                            // 修改用户时新增的角色id，标签用户中增加该用户
                            if (CollectionUtils.isEmpty(tagScopeDto.getUser_ids())) {
                                tagScopeDto.setUser_ids(Collections.singletonList(currentUser));
                                tagScopeService.createRoleUser(tagScopeDto);
                            } else {
                                tagScopeDto.getUser_ids().add(currentUser);
                                tagScopeService.updateRoleUser(tagScopeDto);
                            }
                        } else {
                            // 修改用户时新增的角色id，标签用户中删除该用户
                            tagScopeDto.getUser_ids().remove(currentUser);
                            tagScopeService.updateRoleUser(tagScopeDto);
                            if (tagScopeDto.getUser_ids().size() == 0) {
                                tagScopeDto.setUser_ids(null);
                            }
                        }
                        // 修改管理范围
                        BoServiceUtils.updateMainBo(ModelConst.T_TAG_SCOPE, BeanUtils.bean2Map(tagScopeDto));
                    }
                }
            }
            if (!CollectionUtils.isEmpty(permGroupList)) {
                // 更新角色组信息
                log.info("------------------------更新角色组信息数据：{}------------------------", JSONObject.toJSONString(permGroupList));
                this.permService.updatePermGroupByPermGroupId(permGroupList);
            }
        }
        return updateUserBO;
    }

    /**
     * 根据用户id获取用户信息
     *
     * @param param 用户请求参数
     * @return 用户返回结果
     */
    @Path("getUser")
    @POST
    @Operation(summary = " 根据用户id获取用户信息", tags = CUSTOM_SERVICE)
    public UserDto getUser(@Parameter UserDto param) {
        Assert.notNull(param.getId(), "ID不能为空");

        SingleResponse<BOList> userBO = BoServiceUtils.findListBySimple(ModelConst.T_USER, "id", param.getId());
        if (userBO.getData().getTotal() == 0) {
            throw new BizException("用户ID:" + param.getId() + "不存在");
        }
        UserDto userDto = ObjectMapperUtils.fromJSON(JSONObject.toJSONString(userBO.getData().getData().get(0)), UserDto.class);
        log.info("------------------------根据用户id获取用户信息返回结果：{}------------------------", JSONObject.toJSONString(userDto));
        return userDto;
    }

    /**
     * 使用jdbc查询的方式获取用户信息
     *
     * @param param 用户id
     * @return 用户信息
     */
    @Path("getUserByIdThroughJDBC")
    @POST
    @Operation(summary = " 使用jdbc查询的方式获取用户信息", tags = CUSTOM_SERVICE)
    public UserDto getUserByIdThroughJDBC(@Parameter UserDto param) {
        Assert.notNull(param.getId(), "ID不能为空");

        UserDto user = Objects.requireNonNull(JdbcTemplateUtils.builder(ModelConst.T_USER).selectField("id, account_id, organization_id, department_id, client_id, role_ids," +
                "organization_name, department_name, username, cellphone, email, password, login_reset_password, fullname, qq, expired, locked, credentials_expired," +
                "enabled, protocol_account, job_number, version"))
                .eq("id", param.getId())
                .queryForPOJO(UserDto.class, true);
        if (user == null) {
            throw new BizException("用户ID:" + param.getId() + "不存在");
        }
        log.info("------------------------通过jdbc查询，根据用户id获取用户信息返回结果：{}------------------------", JSONObject.toJSONString(user));
        return user;
    }

    /**
     * 根据用户名获取用户信息
     *
     * @param param 用户名
     * @return 用户返回结果
     */
    @Path("getUserByUsername")
    @POST
    @Operation(summary = " 根据用户名获取用户信息", tags = CUSTOM_SERVICE)
    public UserDto getUserByUsername(@Parameter UserDto param) {
        Assert.notNull(param.getUsername(), "用户名不能为空");
        SingleResponse<BOList> userBO = BoServiceUtils.findListBySimple(ModelConst.T_USER, "username", param.getUsername());
        if (userBO.getData().getTotal() == 0) {
            throw new BizException("用户名:" + param.getUsername() + "不存在");
        }
        UserDto userDto = ObjectMapperUtils.fromJSON(JSONObject.toJSONString(userBO.getData().getData().get(0)), UserDto.class);
        log.info("------------------------根据用户名获取用户信息返回结果：{}------------------------", JSONObject.toJSONString(userDto));
        return userDto;
    }

    /**
     * 获取组织下所有用户信息
     *
     * @param orgName 组织名称
     * @return 组织下用户信息
     */
    public SingleResponse<BOList> getUsersByOrgName(String orgName) {
        Assert.notNull(orgName, "组织名称不能为空");
        SingleResponse<BOList> usersBOList = BoServiceUtils.findListBySimple(ModelConst.T_USER, "organization_name", orgName);
        log.info("------------------------根据组织名称获取到的用户信息：{}------------------------", JSONObject.toJSONString(usersBOList));
        return usersBOList;
    }

    /**
     * 获取部门下所有用户信息
     *
     * @param deptName 部门名称
     * @return 部门下用户信息
     */
    public SingleResponse<BOList> getUsersByDeptName(String deptName) {
        Assert.notNull(deptName, "部门名称不能为空");
        SingleResponse<BOList> usersBOList = BoServiceUtils.findListBySimple(ModelConst.T_USER, "department_name", deptName);
        log.info("------------------------根据部门名称获取到的用户信息：{}------------------------", JSONObject.toJSONString(usersBOList));
        return usersBOList;
    }

    /**
     * 查询用户组织下最高管理员角色
     *
     * @param param 用户id
     * @return 用户信息
     */
    @Path("getOrganizationAdminUser")
    @POST
    @Operation(summary = "查询用户组织下最高管理员角色", tags = CUSTOM_SERVICE)
    public UserDto getOrganizationAdminUser(@Parameter OrganizationDto param) {
        Assert.notNull(param.getId(), "组织ID不能为空");
        OrganizationDto org = organizationApi.getOrg(param);
        SelectorFormat orgFormat = new SelectorFormat();
        orgFormat.setId(org.getId());
        orgFormat.setName(org.getName());
        orgFormat.setType(UnitType.DEPARTMENT.getIndex());
        // 构建方法请求参数
        RoleDto role = RoleDto.builder()
                .organization_id(Collections.singletonList(orgFormat))
                .names(adminRoleNames)
                .build();
        List<RoleDto> rolesByOrgIdAndNames = roleApi.getRolesByOrgIdAndNames(role);
        log.info("---------------------组织:{}查到多个相关的角色：{}---------------------------", param.getId(), rolesByOrgIdAndNames);
        if (rolesByOrgIdAndNames.isEmpty()) {
            return null;
        }

        // 通过角色查询用户
        List<UserDto> userList = Lists.newArrayList();
        for (RoleDto roleDto : rolesByOrgIdAndNames) {
            SingleResponse<BOList> userBOListByRoleIds = BoServiceUtils.findListByLike(ModelConst.T_USER, "role_ids", roleDto.getId());
            if (userBOListByRoleIds.getData().getTotal() > 0) {
                userList.addAll(ObjectMapperUtils.readValue(JSON.toJSONString(userBOListByRoleIds.getData().getData()), UserDto.class));
            }
        }
        log.info("---------------------根据用户id查询最高管理员角色列表返回结果：{}---------------------------", userList);

        if (userList.isEmpty()) {
            return null;
        }
        return userList.get(0);
    }

    /**
     * 根据角色名称查询用户组织角色下所有用户列表
     *
     * @param param 用户id
     * @return 用户信息
     */
    @Path("getOrganizationUserByRoleName")
    @POST
    @Operation(summary = "根据角色名称查询用户组织角色下所有用户列表", tags = CUSTOM_SERVICE)
    public List<UserDto> getOrganizationUserByRoleName(@Parameter UserDto param) {
        Assert.notNull(param.getId(), "用户ID不能为空");
        UserDto userById = getUserByIdThroughJDBC(param);
        String[] columns = new String[]{"name", "organization_id"};
        Operator[] operators = new Operator[]{Operator.LIKE, Operator.LIKE};
        Object[] columnsVal = new Object[]{param.getRoleName(), userById.getOrganization_id().get(0)};
        SingleResponse<BOList> roleBOList = BoServiceUtils.findListByComplex(ModelConst.T_ROLE, columns, columnsVal, operators);
        if (!roleBOList.isSuccess()) {
            Exceptions.throwBizException(ErrorCodeEnum.BO_LIST_ERROR);
        }
        log.info("------------------------根据组织id和角色名称获取角色列表返回结果：{}------------------------", JSONObject.toJSONString(roleBOList));
        if (roleBOList.getData().getTotal() == 0) {
            return Lists.newArrayList();
        }
        SingleResponse<BOList> userBOListByRoleIds = BoServiceUtils.findListByLike(ModelConst.T_USER, "role_ids", roleBOList.getData().getData().get(0).get("id"));
        if (userBOListByRoleIds.getData().getTotal() == 0) {
            return Lists.newArrayList();
        }
        log.info("------------------------根据角色id获取用户列表返回结果：{}------------------------", JSONObject.toJSONString(userBOListByRoleIds));
        return ObjectMapperUtils.readValue(JSONObject.toJSONString(userBOListByRoleIds.getData().getData()), UserDto.class);
    }

    /**
     * 根据部门管理员获取下属员工id列表,根据组织管理员获取组织所有员工id列表
     *
     * @param userDto 用户id
     * @return 员工id列表
     */
    @Path("listSubMemberIds")
    @POST
    @Operation(summary = "根据部门管理员获取下属员工id列表,根据组织管理员获取组织所有员工id列表", tags = CUSTOM_SERVICE)
    public List<String> listSubMemberIds(@Parameter UserDto userDto) {
        Set<String> ids = new HashSet<>();
        // 获取用户信息
        UserDto user = getUserByIdThroughJDBC(userDto);
        if (StringUtils.isEmpty(user.getRole_ids())) {
            return Lists.newArrayList();
        }

        String[] roleIds = user.getRole_ids().split(",");
        List<String> roleIdList = Arrays.asList(roleIds);
        SingleResponse<BOList> roleBOList = BoServiceUtils.findListByIn(ModelConst.T_ROLE, "id", roleIdList);
        log.info("--------------------根据角色id列表获取角色列表数据：{}--------------------", JSONObject.toJSONString(roleBOList));
        List<String> roleNameList = roleBOList.getData().getData().stream().map(roleMap -> roleMap.get("name").toString()).distinct().collect(Collectors.toList());
        for (String roleName : roleNameList) {
            //如果是平台角色则返回空用于查询所有
            if (roleName.startsWith("ROLE_PM_")) {
                return Lists.newArrayList();
            }
        }
        // 部门管理员
        if (CollectionUtils.containsAny(roleNameList, Sets.newHashSet("ROLE_VENDOR_DEPT_ADMIN", "ROLE_CUSTOMER_DEPT_ADMIN"))) {
            SingleResponse<BOList> userBOListByDeptId = BoServiceUtils.findListBySimple(ModelConst.T_USER, "department_id", user.getDepartment_id().get(0));
            userBOListByDeptId.getData().getData().stream().map(userMap -> String.valueOf(userMap.get("id"))).forEach(ids::add);
        }
        // 组织管理员
        if (CollectionUtils.containsAny(roleNameList, Sets.newHashSet("ROLE_CUSTOMER_ORG_ADMIN", "ROLE_VENDOR_ORG_ADMIN", "ROLE_CUSTOMER_ADMIN", "ROLE_VENDOR_ADMIN"))) {
            List<OrganizationDto> organizationList = organizationApi.getOrgListByOrgId(OrganizationDto.builder().id(user.getOrganization_id().get(0).getId()).build());
            List<String> orgNameList = organizationList.stream().map(OrganizationDto::getName).collect(Collectors.toList());
            SingleResponse<BOList> userBOListByOrgNames = BoServiceUtils.findListByIn(ModelConst.T_USER, "organization_name", orgNameList);
            userBOListByOrgNames.getData().getData().stream().map(userMap -> String.valueOf(userMap.get("id"))).forEach(ids::add);
        }
        ids.add(user.getId());
        return Lists.newArrayList(ids);
    }

    /**
     * 获取组织内的用户ID列表
     *
     * @param organizationDto 组织id
     * @return 用户列表
     */
    @Path("listSubMemberIdsByOrganizationId")
    @POST
    @Operation(summary = " 获取组织内的用户ID列表", tags = CUSTOM_SERVICE)
    public List<String> listSubMemberIdsByOrganizationId(@Parameter OrganizationDto organizationDto) {
        Assert.notEmpty(organizationDto.getIds(), "组织ID不能为空");
        StringBuilder sql = new StringBuilder();
        Map<String, Object> parameter = Maps.newHashMap();
        sql.append("select id from\n");
        sql.append(JdbcTemplateUtils.getTableName(ModelConst.T_USER)).append(" u \n");
        sql.append("where 1 =1\n");
        sql.append("and CASE WHEN JSON_VALID(u.organization_id) THEN JSON_UNQUOTE(u.organization_id -> '$.id') in (select org.id from ")
                .append(JdbcTemplateUtils.getTableName(ModelConst.T_ORGANIZATION)).append(" org\n");
        sql.append("where org.id in (:orgIds) or CASE WHEN JSON_VALID(org.parent_id) THEN JSON_UNQUOTE( org.parent_id -> '$.id' )  in (:orgIds) ELSE NULL END\n");
        sql.append("and org.deleted = 0)\n");
        sql.append("ELSE NULL END\n");
        sql.append("and u.deleted = 0\n");
        // 组织id去重
        parameter.put("orgIds", organizationDto.getIds().stream().distinct().collect(Collectors.toList()));
        log.info("sql = {}, parameters = {}", sql, JSONObject.toJSONString(parameter));
        List<String> result = jdbcTemplate.queryForList(sql.toString(), parameter, String.class);
        if (CollectionUtils.isEmpty(result)) {
            return Lists.newArrayList();
        }
        return result;
    }

    /**
     * 设置用户选人控件冗余名称
     *
     * @param user 用户信息
     */
    private void setUserValue(UserDto user) {
        if (!CollectionUtils.isEmpty(user.getOrganization_id())) {
            user.setOrganization_name(user.getOrganization_id().get(0).getName());
        } else {
            user.setOrganization_name("");
            user.setOrganization_id(null);
        }
        if (!CollectionUtils.isEmpty(user.getDepartment_id())) {
            user.setDepartment_name(user.getDepartment_id().get(0).getName());
        } else {
            user.setDepartment_name("");
            user.setDepartment_id(null);
        }
    }

    /**
     * 用户修改记录
     *
     * @param newUserJSON 更前后的用户信息
     * @param oldUserJSON 更新前的用户信息
     */
    private void userRecord(JSONObject newUserJSON, JSONObject oldUserJSON) {
        List<Map<String, Object>> userRecordList = Lists.newArrayList();
        Map<String, Object> userMap = Maps.newHashMap();
        SelectorFormat user = new SelectorFormat();
        user.setType(UnitType.USER.getIndex());
        user.setId(oldUserJSON.getString("id"));
        user.setName(newUserJSON.getString("fullname"));
        userMap.put("user_id", user);
        userMap.put("memo", "测试");
        Set<String> keys = oldUserJSON.keySet();
        for (String key : keys) {
            if (!"index".equals(key)) {
                String oldValue = JSON.toJSONString(oldUserJSON.get(key));
                String newValue = JSON.toJSONString(newUserJSON.get(key));
                if (!oldValue.equals(newValue)) {
                    Map<String, Object> recordMap = Maps.newHashMap(userMap);
                    recordMap.put("column_name", key);
                    recordMap.put("old_value", oldValue.replaceAll("\"", ""));
                    recordMap.put("new_value", newValue.replaceAll("\"", ""));
                    userRecordList.add(recordMap);
                }
            }
        }
        log.info("------------------------系统管理用户修改记录：{}------------------------", JSONObject.toJSONString(userRecordList));
        BoServiceUtils.createBo(ModelConst.T_USER_RECORD, userRecordList);
    }

    /**
     * 构建云枢系统人员信息
     *
     * @param user 用户信息
     * @return 云枢人员信息
     */
    private UserV2 buildUserV2(UserDto user) {
        // 设置用户信息
        UserV2 userV2 = new UserV2();
        if (!StringUtils.isEmpty(user.getId())) {
            userV2.setId(user.getId());
        }
        // 姓名：name  账号：username
        userV2.setName(user.getFullname());
        userV2.setUsername(user.getUsername());
        userV2.setMobile(user.getCellphone());
        userV2.setEmail(user.getEmail());
        userV2.setOrganizationId(user.getOrganization_id().get(0).getId());
        userV2.setMainDepartmentId(user.getDepartment_id().get(0).getId());
        // 测试组织id
        userV2.setOrganizationId("2");
        // todo 先默认，回头加上
        userV2.setGender(GenderType.MALE);
        userV2.setEntryDate(new Date());
        userV2.setImgUrl("");
        userV2.setPosition("");
        userV2.setEmployeeNo("");
        userV2.setOfficePhone("");
        return userV2;
    }

    /**
     * 获取角色id差集
     *
     * @param oldRoleIdList 修改之前的角色id列表
     * @param newRoleIdList 修改之后的角色id列表
     * @return 角色id差集
     */
    private List<String> getDifferenceList(List<String> oldRoleIdList, List<String> newRoleIdList) {
        // 角色id并集
        List<String> unionList = Lists.newArrayList();
        unionList.addAll(oldRoleIdList);
        unionList.addAll(newRoleIdList);
        unionList = unionList.stream().distinct().collect(Collectors.toList());

        // 角色id交集
        List<String> intersectionList = Lists.newArrayList(oldRoleIdList);
        intersectionList.retainAll(newRoleIdList);

        // 角色id差集
        List<String> differenceList = unionList.stream().filter(id -> !intersectionList.contains(id)).collect(Collectors.toList());
        log.info("------------------------用户角色id差集：{}------------------------", JSONObject.toJSONString(differenceList));
        return differenceList;
    }
}
